-
Notifications
You must be signed in to change notification settings - Fork 2
Build GitHub repository integration for PageSpace #37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Build GitHub repository integration for PageSpace #37
Conversation
Implemented complete backend infrastructure for GitHub Integration feature: Database Schema: - Created github_connections table for OAuth tokens and user GitHub info - Created github_repositories table for connected repositories with metadata - Created github_code_embeds table for living code references in documents - Created github_search_cache table for performance optimization - Added migration 0006_github_integration.sql with proper indexes and foreign keys GitHub Service (packages/lib/src/services/github-service.ts): - GitHubService class for all GitHub API interactions - OAuth token encryption/decryption utilities - Methods for repository listing, file browsing, and code search - GitHubOAuth class for OAuth flow management - Support for branches, commits, and file content retrieval - Language detection from file extensions API Routes (apps/web/src/app/api/github/): - /auth/connect - Initiate GitHub OAuth flow with CSRF protection - /auth/callback - Handle OAuth callback and store encrypted tokens - /connections - Manage GitHub connections (list, validate, delete) - /repositories - Connect/disconnect repos, list available/connected repos - /search - Search code across connected repositories with caching - /files - Browse repository files and create code embeds Features: - Complete OAuth 2.0 flow with state parameter for CSRF protection - Encrypted token storage using encryption-utils - Permission-based access control (drive ownership and membership) - Rate limiting on OAuth endpoints - Search result caching with 1-hour expiration - Support for line-range code snippets - Automatic language detection for syntax highlighting - Repository sync metadata tracking Security: - All tokens encrypted before database storage - Permission checks on all operations - Rate limiting on authentication endpoints - State validation with timestamp expiry (10 minutes) - Drive-level access control for all repository operations
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // Decode and validate state | ||
| let stateData: { | ||
| state: string; | ||
| userId: string; | ||
| driveId?: string; | ||
| returnUrl?: string; | ||
| timestamp: number; | ||
| }; | ||
|
|
||
| try { | ||
| const decodedState = Buffer.from(encodedState, 'base64url').toString('utf-8'); | ||
| stateData = JSON.parse(decodedState); | ||
|
|
||
| // Validate state timestamp (prevent replay attacks, 10 minutes expiry) | ||
| const stateAge = Date.now() - stateData.timestamp; | ||
| if (stateAge > 10 * 60 * 1000) { | ||
| loggers.auth.warn('Expired GitHub OAuth state', { age: stateAge }); | ||
| return NextResponse.redirect(new URL('/settings?error=github_state_expired', baseUrl)); | ||
| } | ||
| } catch (e) { | ||
| loggers.auth.error('Invalid GitHub OAuth state', e as Error); | ||
| return NextResponse.redirect(new URL('/settings?error=github_invalid_state', baseUrl)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Verify OAuth state with a server-side secret
The callback decodes the state query parameter and only enforces a timestamp check before using the embedded userId to upsert a connection later in the handler. Because the value is merely base64‑encoded JSON with no server lookup or signature, anyone who knows a victim’s user ID can forge a state payload and complete the OAuth flow to bind their GitHub token to that victim account. This defeats the CSRF protection that the state parameter is meant to provide. Persist or sign the state on the server before trusting it.
Useful? React with 👍 / 👎.
Implemented complete backend infrastructure for GitHub Integration feature:
Database Schema:
GitHub Service (packages/lib/src/services/github-service.ts):
API Routes (apps/web/src/app/api/github/):
Features:
Security: